package org.one.stone.soup.grfxML.plugin.javascript;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.EcmaError;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.one.stone.soup.grfxML.DataText;
import org.one.stone.soup.grfxML.GrfxMLEngine;
import org.one.stone.soup.grfxML.plugin.SimplePlugin;
import org.one.stone.soup.grfxML.plugin.grfxMLCaster;
import org.one.stone.soup.mjdb.data.field.DataLinker;
import org.one.stone.soup.mjdb.data.field.Field;

public class JavascriptPlugin extends SimplePlugin {

	public static final int ARG_INIT = 0;
	public static final int ARG_PROCESS = 1;
	public static final int ARG_STOP = 2;

	private DataText init = new DataText();
	private DataText process = new DataText();
	private DataText stop = new DataText();

	private Context cx;
	private Scriptable scope;

	public JavascriptPlugin(GrfxMLEngine engine)
	{
		super(engine);
		
		cx = Context.enter();
		scope = cx.initStandardObjects();
	}

	public void initialize() {
		Object wrappedOut = Context.toObject( getEngine().getAPI(), scope); 
		ScriptableObject.putProperty(scope, "Giraffe", wrappedOut);

		wrappedOut = Context.toObject( this, scope); 
		ScriptableObject.putProperty(scope, "Javascript", wrappedOut);
		
		runScript(init);
	}

	public void register(DataLinker store) 
	{
		init = grfxMLCaster.cast(init,getArg(init,ARG_INIT,store));
		process = grfxMLCaster.cast(process,getArg(process,ARG_PROCESS,store));
		stop = grfxMLCaster.cast(stop,getArg(stop,ARG_STOP,store));
	}
	public void replace(Field oldObj, Field newObj)
	{
		init = grfxMLCaster.replace(init,oldObj,newObj);
		process = grfxMLCaster.replace(process,oldObj,newObj);
		stop = grfxMLCaster.replace(stop,oldObj,newObj);
	}

	public void stop() {
		runScript(stop);

	}

	public void process() {
		runScript(process);
	}

	public void say(Object data)
	{
		System.out.println(data);
	}

	private void runScript(DataText script) {
		
		StringBuffer scriptText = new StringBuffer();
		for(int loop=0;loop<script.size();loop++)
		{
			String line = script.get(loop).getValue();
			
			scriptText.append(line);
			scriptText.append('\n');
		}
		
		try{
			cx = Context.enter();
			cx.evaluateString(scope, scriptText.toString(), script.getId(), 1, null);
		}
		catch(EcmaError ee)
		{
			System.out.println( "Javascript Error: "+ee );
		}
		catch(Exception e)
		{
			System.out.println( "JavascriptPlugin Exception: "+e );
		}
	}
}
